package com.one.blocks.mvc.manager;

import com.one.blocks.mvc.domain.Id;
import com.one.blocks.mvc.mapper.BaseMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:idler41@163.com">linfuxin</a> created by 2022-06-03 16:56:05
 */
@Slf4j
public abstract class AbstractBatchManager<Mapper extends BaseMapper<T>, T extends Id<? extends Serializable>> extends AbstractManager<Mapper, T> implements BatchManager<T> {

    public AbstractBatchManager(Mapper mapper) {
        super(mapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertBatch(List<T> list) {
        for (T t : list) {
            mapper.insert(t);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertBatchOfBreakIfException(List<T> list) {
        for (int i = 0, size = list.size(); i < size; i++) {
            T t = list.get(i);
            try {
                mapper.insert(t);
            } catch (RuntimeException e) {
                return i;
            }
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<T> insertBatchOfIgnoreIfException(List<T> list) {
        List<T> errorData = null;
        for (T t : list) {
            try {
                mapper.insert(t);
            } catch (RuntimeException e) {
                if (errorData == null) {
                    errorData = new ArrayList<>();
                }
                errorData.add(t);
            }
        }
        return errorData;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateBatchById(List<T> list) {
        for (T t : list) {
            mapper.updateById(t);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBatch(List<T> list) {
        for (T t : list) {
            if (t.getId() == null) {
                mapper.insert(t);
            } else {
                mapper.updateById(t);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer updateBatchByIdOfBreakIfException(List<T> list) {
        for (int i = 0, size = list.size(); i < size; i++) {
            T t = list.get(i);
            try {
                mapper.updateById(t);
            } catch (RuntimeException e) {
                return i;
            }
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<T> updateBatchByIdOfIgnoreIfException(List<T> list) {
        List<T> errorData = null;
        for (T t : list) {
            try {
                mapper.updateById(t);
            } catch (RuntimeException e) {
                if (errorData == null) {
                    errorData = new ArrayList<>();
                }
                errorData.add(t);
            }
        }
        return errorData;
    }
}
